<template>
  <div class="levelTree">
    <el-input
      placeholder="输入关键字进行过滤"
      v-model="filterText"
      style="margin-bottom: 15px"
    >
    </el-input>
    <el-tree
      ref="nodeTree"
      :data="nodeTreeData"
      node-key="id"
      default-expand-all
      highlight-current
      :expand-on-click-node="false"
      class="node-tree"
      icon-class="el-icon-arrow-right"
      :filter-node-method="filterNode"
      @node-click="onNodeTreeClick"
    >
      <span slot-scope="{ node, data }" class="nodeContent">
        <svg-icon :icon-class="currIcon(data)" class-name="color-svg-icon" />
        <!-- <span class="nodeLabel">{{ node.label }} </span> -->
        <span class="nodeLabel" v-if="data.type === 'page'">Page </span>
        <span class="nodeLabel" v-else
          >{{
            i18n2t(
              `designer.widgetLabel.${data.type}`,
              `extension.widgetLabel.${data.type}`
            )
          }}
          {{ data.label ? "(" + data.label + ")" : "" }}</span
        >
      </span>
    </el-tree>
  </div>
</template>

<script>
import { traverseAllWidgets } from "@/utils/util";
import {
  advancedFields,
  basicFields,
  dataBox,
  containers,
  customFields,
  layoutFields,
} from "@/components/form-designer/widget-panel/widgetsConfig";
import SvgIcon from "@/components/svg-icon/index.vue";
import i18n from "@/utils/i18n";

export default {
  name: "levelTree",
  props: {
    designer: Object,
  },
  mixins: [i18n],
  components: { SvgIcon },
  data() {
    return {
      nodeTreeData: [],
      filterText: "",
      compArr: [
        ...advancedFields,
        ...basicFields,
        ...dataBox,
        ...containers,
        ...customFields,
        ...layoutFields,
      ],
    };
  },
  methods: {
    currIcon(data) {
      const [selected] = this.compArr.filter((v) => v.type === data.type);
      if (selected) {
        return selected.icon;
      }
      return null;
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    showNodeTreeDrawer() {
      this.refreshNodeTree();
      this.$nextTick(() => {
        if (this.designer.selectedId) {
          //同步当前选中组件到节点树！！！
          this.$refs.nodeTree.setCurrentKey(this.designer.selectedId);
        }
      });
    },
    buildTreeNodeOfWidget(widget, treeNode) {
      if(!widget){
        return
      }
      let curNode = {
        id: widget.id,
        label: (widget.options && widget.options.label) || widget.type,
        type: widget.type,
        //selectable: true,
      };
      treeNode.push(curNode);
      if (widget.category === undefined) {
        return;
      }
      curNode.children = [];
      if (widget.type === "grid") {
        widget.cols.map((col) => {
            let colNode = {
              id: col.id,
              label: col.options.name || col.type,
              type: col.type,
              children: [],
            };
            curNode.children.push(colNode);
            col.widgetList &&
              col.widgetList.map((wChild) => {
                this.buildTreeNodeOfWidget(wChild, colNode.children);
              });
              col.cols &&
              col.cols.map((wChild) => {
                this.buildTreeNodeOfWidget(wChild, colNode.children);
              });
        });
      } else if (widget.type === "table") {
        widget.rows.map((row) => {
          let rowNode = {
            id: row.id,
            // label: "table-row",
            label: "表格",
            selectable: false,
            children: [],
            type: "table",
          };
          curNode.children.push(rowNode);

          row.cols.map((cell) => {
            if (cell.merged) {
              //跳过合并单元格！！
              return;
            }

            let rowChildren = rowNode.children;
            let cellNode = {
              id: cell.id,
              // label: "table-cell",
              label: "table-cell",
              type: "table-cell",
              children: [],
            };
            rowChildren.push(cellNode);

            cell.widgetList.map((wChild) => {
              this.buildTreeNodeOfWidget(wChild, cellNode.children);
            });
          });
        });
      } else if (widget.type === "tab") {
        widget.tabs.map((tab) => {
          let tabNode = {
            id: tab.id,
            label: tab.options.name || widget.type,
            selectable: false,
            type: widget.type,
            children: [],
          };
          curNode.children.push(tabNode);
          tab.widgetList.map((wChild) => {
            this.buildTreeNodeOfWidget(wChild, tabNode.children);
          });
        });
      } else if (widget.type === "sub-form") {
        widget.widgetList.map((wChild) => {
          this.buildTreeNodeOfWidget(wChild, curNode.children);
        });
      } else if (widget.category === "container") {
        //自定义容器
        widget.widgetList && widget.widgetList.map((wChild) => {
          this.buildTreeNodeOfWidget(wChild, curNode.children);
        });
      }
    },
    refreshNodeTree() {
      this.nodeTreeData.length = 0;
      this.designer.widgetList.forEach((wItem) => {
        this.buildTreeNodeOfWidget(wItem, this.nodeTreeData);
      });
      this.nodeTreeData = [
        {
          id: "page",
          label: "Page",
          type: "page",
          children: this.nodeTreeData,
        },
      ];
    },
    onNodeTreeClick(nodeData, node, nodeEl) {
      if (nodeData.selectable !== undefined && !nodeData.selectable) {
        this.$message.info(
          this.i18nt("designer.hint.currentNodeCannotBeSelected")
        );
      } else {
        const selectedId = nodeData.id;
        const foundW = this.findWidgetById(selectedId);
        if (foundW) {
          this.designer.setSelected(foundW);
        }
      }
    },
    findWidgetById(wId) {
      let foundW = null;
      traverseAllWidgets(this.designer.widgetList, (w) => {
        if (w.id === wId) {
          foundW = w;
        }
      });
      return foundW;
    },
  },
  mounted() {
    this.showNodeTreeDrawer();
  },
  watch: {
    filterText(val) {
      this.$refs.nodeTree.filter(val);
    },
    "designer.widgetList": {
      handler(v) {
        this.showNodeTreeDrawer();
        if (v.length === 0) {
          this.nodeTreeData = [];
        }
      },
      deep: true,
      immediate: true,
    },
    "designer.selectedId": {
      handler(v) {
        if (v) {
          this.$nextTick(() => {
            this.$refs.nodeTree.setCurrentKey(v);
          });
        }
      },
      deep: true,
      immediate: true,
    },
  },
};
</script>

<style scoped lang="scss">
.color-svg-icon {
  -webkit-font-smoothing: antialiased;
  color: #7c7d82;
}
.levelTree {
  width: 100%;
  padding: 10px 15px;
  box-sizing: border-box;
}
.nodeContent {
  display: flex;
  align-items: center;
}
.nodeLabel {
  font-size: 14px;
  margin-left: 10px;
}
.node-tree ::v-deep {
  .el-tree > .el-tree-node:after {
    border-top: none;
  }

  .el-tree-node {
    position: relative;
    padding-left: 12px;
  }
  .el-tree-node__content {
    padding-left: 0 !important;
    height: 35px;
    line-height: 35px;
  }

  .el-tree-node__expand-icon.is-leaf {
    display: none;
  }

  .el-tree-node__children {
    padding-left: 12px;
    overflow: visible !important; /* 加入此行让el-tree宽度自动撑开，超出宽度el-draw自动出现水平滚动条！ */
  }

  .el-tree-node :last-child:before {
    height: 38px;
  }

  .el-tree > .el-tree-node:before {
    border-left: none;
  }

  .el-tree > .el-tree-node:after {
    border-top: none;
  }

  .el-tree-node:before {
    content: "";
    left: -4px;
    position: absolute;
    right: auto;
    border-width: 1px;
  }

  .el-tree-node:after {
    content: "";
    left: -4px;
    position: absolute;
    right: auto;
    border-width: 1px;
  }

  .el-tree-node:before {
    border-left: 1px dashed #4386c6;
    bottom: 0px;
    height: 100%;
    top: -10px;
    width: 1px;
  }

  .el-tree-node:after {
    border-top: 1px dashed #4386c6;
    height: 20px;
    top: 12px;
    width: 16px;
  }

  .el-tree-node.is-current > .el-tree-node__content {
    background: #c2d6ea !important;
  }

  .el-tree-node__expand-icon {
    margin-left: -3px;
    padding: 6px 6px 6px 0px;
    font-size: 16px;
  }
}
</style>
